package com.cskaoyan.mall.pay.service.impl;

import com.cskaoyan.mall.commons.constant.SysRetCodeConstants;
import com.cskaoyan.mall.commons.exception.ExceptionProcessorUtils;
import com.cskaoyan.mall.commons.exception.ProcessException;
import com.cskaoyan.mall.order.dto.PayOrderSuccessRequest;
import com.cskaoyan.mall.order.dto.PayOrderSuccessResponse;
import com.cskaoyan.mall.pay.api.OrderApi;
import com.cskaoyan.mall.pay.constant.PayRetCode;
import com.cskaoyan.mall.pay.constants.PayChannel;
import com.cskaoyan.mall.pay.constants.PayResult;
import com.cskaoyan.mall.pay.dal.entitys.Payment;
import com.cskaoyan.mall.pay.dal.persistence.PaymentMapper;
import com.cskaoyan.mall.pay.dto.PaymentRequest;
import com.cskaoyan.mall.pay.dto.alipay.AlipayQueryRetResponse;
import com.cskaoyan.mall.pay.dto.alipay.AlipaymentResponse;
import com.cskaoyan.mall.pay.service.PayCoreService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;

/**
 * @auther cskaoyan
 * @date 2022/6/22:11:33
 */
@Slf4j
@Service
public class PayCoreServiceImpl implements PayCoreService {

    @Autowired
    PayHelper payHelper;

    @Autowired
    OrderApi orderApi;

    @Autowired
    PaymentMapper paymentMapper;


    /**
     * @param [request]
     * @return com.cskaoyan.mall.pay.dto.alipay.AlipaymentResponse
     * @author 牟治宇
     * @description 获取支付二维码
     * @date 2022/8/3 15:37
     */
    @Override
    public AlipaymentResponse aliPay(PaymentRequest request) {
        AlipaymentResponse alipaymentResponse = new AlipaymentResponse();
        log.info("访问支付宝，获取支付二维码");
        // 1. 获取支付二维码图片的名字
        String codeFileName = payHelper.test_trade_precreate(request);

        if (codeFileName == null) {
            // 获取支付二维码失败
            log.error("如果获取支付二维码失败");
            alipaymentResponse.setCode(PayRetCode.GET_CODE_FALIED.getCode());
            alipaymentResponse.setMsg(PayRetCode.GET_CODE_FALIED.getMsg());
            return alipaymentResponse;
        }

        // tb_payment 插入一条记录，订单的支付信息  TRADE_PROCESSING
        Payment payment = new Payment();
        payment.setOrderId(request.getTradeNo());
        payment.setStatus(PayResult.TRADE_PROCESSING.getCode());
        payment.setPayerUid(request.getUserId());
        payment.setPayerAmount(request.getOrderFee());
        payment.setOrderAmount(request.getTotalFee());
        payment.setPayWay(request.getPayChannel());
        payment.setPayerName(request.getNickName());
        payment.setCreateTime(new Date());
        payment.setUpdateTime(new Date());
        payment.setRemark(PayChannel.ALI_PAY.getDesc());
        int effectRows = paymentMapper.insertSelective(payment);
        if (effectRows != 1) {
            log.error("tb_payment插入失败！");
            throw new ProcessException(SysRetCodeConstants.DB_EXCEPTION.getCode(), SysRetCodeConstants.DB_EXCEPTION.getMessage());
        }
        // 设置二维码图片的名字，成功的响应码以及描述信息
        alipaymentResponse.setQrCode(codeFileName);
        alipaymentResponse.setCode(PayRetCode.SUCCESS.getCode());
        alipaymentResponse.setMsg(PayRetCode.SUCCESS.getMsg());
        return alipaymentResponse;
    }

    /**
     * @param [request]
     * @return com.cskaoyan.mall.pay.dto.alipay.AlipayQueryRetResponse
     * @author 牟治宇
     * @description 获取订单支付结果
     * @date 2022/8/3 15:36
     */
    @Override
    public AlipayQueryRetResponse queryAlipayRet(PaymentRequest request) {

        AlipayQueryRetResponse response = new AlipayQueryRetResponse();

        try {
            // 根据订单id查询支付结果
            request.requestCheck();
            String orderId = request.getTradeNo();
            boolean success = payHelper.test_trade_query(orderId);
            if (success) {
                // 更新 tb_payment  支付状态 TRADE_SUCCESS  支付成功时间 支付完成时间
                Example example = new Example(Payment.class);
                example.createCriteria().andEqualTo("orderId", request.getTradeNo());
                Payment payment = new Payment();
                payment.setStatus(PayResult.TRADE_SUCCESS.getCode());
                payment.setPaySuccessTime(new Date());
                payment.setUpdateTime(new Date());
                payment.setCompleteTime(new Date());
                int effectRows = paymentMapper.updateByExampleSelective(payment, example);
                if (effectRows != 1) {
                    log.error("修改支付信息失败！");
                    throw new ProcessException(SysRetCodeConstants.DB_EXCEPTION.getCode(), SysRetCodeConstants.DB_EXCEPTION.getMessage());
                }
                log.info("tb_payment插入成功 orderId {}", orderId);
                // 调用订单服务，执行以下操作
                //orderApi.payOrderSuccess()
                // 更新订单状态   已支付
                PayOrderSuccessRequest successRequest = new PayOrderSuccessRequest();
                successRequest.setOrderId(request.getTradeNo());
                PayOrderSuccessResponse successResponse = orderApi.payOrderSuccess(successRequest);
                if (successResponse.getCode().equals(PayRetCode.SUCCESS.getCode())) {
                    response.setCode(PayRetCode.SUCCESS.getCode());
                    response.setMsg(PayRetCode.SUCCESS.getMsg());
                } else {
                    log.error("订单修改失败");
                    throw new ProcessException(SysRetCodeConstants.DB_EXCEPTION.getCode(), SysRetCodeConstants.DB_EXCEPTION.getMessage());
                }
            } else {
                // 更新 tb_payment 支付状态 FAIL， 支付完成之间
                Example example = new Example(Payment.class);
                example.createCriteria().andEqualTo("orderId", request.getTradeNo());
                Payment payment = new Payment();
                payment.setStatus(PayResult.FAIL.getCode());
                payment.setCompleteTime(new Date());
                int effectRows = paymentMapper.updateByExampleSelective(payment, example);
                if (effectRows != 1) {
                    log.error("修改支付信息失败！");
                    throw new ProcessException(SysRetCodeConstants.DB_EXCEPTION.getCode(), SysRetCodeConstants.DB_EXCEPTION.getMessage());
                }
                response.setCode(PayRetCode.PAYMENT_PROCESSOR_FAILED.getCode());
                response.setMsg(PayRetCode.PAYMENT_PROCESSOR_FAILED.getMsg());
            }
        } catch (ProcessException e) {
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }
}
